package com.android.lovely.framework

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import com.kotlin.extensions.inflater.LayoutInflaterExt.layoutInflater
import java.lang.reflect.ParameterizedType

/**
 *
 * @author why
 * @date 2025/3/7 15:28
 */
abstract class BaseAdapter<T, VB : ViewBinding>(
    dataList: List<T> = emptyList()
) : RecyclerView.Adapter<BaseAdapter<T, VB>.ViewHolder>() {

    protected val list = dataList.toMutableList()

    var onItemClick: ((item: T?, position: Int) -> Unit)? = null

    fun getItems(): List<T> = list

    @SuppressLint("NotifyDataSetChanged")
    open fun updateList(newList: List<T>) {
        list.clear()
        list.addAll(newList)
        notifyDataSetChanged()
    }

    fun insert(item: T, position: Int = list.size) {
        list.add(position, item)
        notifyItemInserted(position)
    }

    fun insertList(newItems: List<T>, position: Int = list.size) {
        list.addAll(position, newItems)
        notifyItemRangeInserted(position, newItems.size)
    }

    fun delete(item: T) {
        val index = list.indexOf(item)
        if (index >= 0) {
            deleteAt(index)
        }
    }

    fun deleteAt(index: Int) {
        if (index in list.indices) {
            list.removeAt(index)
            notifyItemRemoved(index)
            notifyItemRangeChanged(index, list.size - index)
        }
    }

    protected fun getItemAt(position: Int): T? {
        if (position > list.size) {
            return null
        }
        return list[position]
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(inflateBinding(parent))
    }

    override fun getItemCount() = list.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.binding.root.setOnClickListener {
            onItemClick?.invoke(getItemAt(position), position)
        }
        bindViewWithHolderDetails(holder, getItemAt(position), holder.binding, position)
    }

    abstract fun bindViewWithHolderDetails(holder: ViewHolder, item: T?, binding: VB, position: Int)

    private fun inflateBinding(parent: ViewGroup): VB {
        val bindingClass =
            (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[1] as Class<VB>
        val method = bindingClass.getDeclaredMethod(
            "inflate", LayoutInflater::class.java, ViewGroup::class.java, Boolean::class.java
        )
        return method.invoke(null, parent.layoutInflater, parent, false) as VB
    }

    inner open class ViewHolder(val binding: VB) : RecyclerView.ViewHolder(binding.root)
}